unit GdipBitmap;

interface

uses
  GdipObj, GdipAPI, GdiPUtil, Windows, SysUtils, Classes, Graphics;

type
  TGdipBitmap = class(TBitmap)
  public
    procedure LoadFromStream(Stream: TStream); override;
    procedure SaveToFile(const Filename: string); override;
    procedure SaveToStream(Stream: TStream); override;
  end;

var
  BackgroundColor: TColor = clBtnFace;

implementation

{ TGdipBitmap }

var
  ImageFormat: string = '';

procedure SetImageFormat(const Filename: string);
begin
  ImageFormat := ExtractFileExt(Filename);
  if ImageFormat <> '' then
  begin
    Delete(ImageFormat, 1, 1);
    if CompareText(ImageFormat, 'jpg') = 0 then
      ImageFormat := 'jpeg'
    else if CompareText(ImageFormat, 'tif') = 0 then
      ImageFormat := 'tiff';
  end else ImageFormat := 'bmp';
  ImageFormat := 'image/' + ImageFormat;
end;

procedure TGdipBitmap.LoadFromStream(Stream: TStream);
var
  Adaper: TStreamAdapter;
  tmp: TGpBitmap;
  h: HBITMAP;
begin
  Adaper := TStreamAdapter.Create(Stream, soReference);
  tmp := TGpBitmap.Create(Adaper);
  try
    case tmp.GetPixelFormat of
      PixelFormat1bppIndexed: PixelFormat := pf1bit;
      PixelFormat4bppIndexed: PixelFormat := pf4bit;
      PixelFormat8bppIndexed: PixelFormat := pf8bit;
      PixelFormat16bppRGB565,
      PixelFormat16bppRGB555,
      PixelFormat16bppARGB1555: PixelFormat := pf16bit;
      PixelFormat24bppRGB:      PixelFormat := pf24bit;
      PixelFormat32bppRGB,
      PixelFormat32bppARGB:     PixelFormat := pf32bit;
      else PixelFormat := pfCustom;
    end;
    tmp.GetHBITMAP(DWord(BackgroundColor), h);
    Handle := h;
  finally
    tmp.Free;
  end;
end;

procedure TGdipBitmap.SaveToFile(const Filename: string);
begin
  SetImageFormat(Filename);
  inherited SaveToFile(Filename);
  ImageFormat := '';
end;

procedure TGdipBitmap.SaveToStream(Stream: TStream);
var
  tmp: TGpBitmap;
  Adaper: TStreamAdapter;
  Clsid: TGUID;
begin
  if (ImageFormat <> '') and (GetEncoderClsid(ImageFormat, Clsid) <> -1) then
  begin
    tmp := TGpBitmap.Create(Handle, Palette);
    try
      Adaper := TStreamAdapter.Create(Stream, soReference);
      tmp.Save(Adaper, Clsid);
    finally
      tmp.Free;
    end;
  end else
    inherited SaveToStream(Stream);
end;

initialization
  //TPicture.RegisterFileFormat('bmp', 'BMP File', TGdipBitmap);
  TPicture.RegisterFileFormat('Exif', 'TIFF File', TGdipBitmap);
  TPicture.RegisterFileFormat('tiff', 'TIFF File', TGdipBitmap);
  TPicture.RegisterFileFormat('tif', 'TIFF File', TGdipBitmap);
  TPicture.RegisterFileFormat('png', 'PNG File', TGdipBitmap);
  TPicture.RegisterFileFormat('gif', 'GIF File', TGdipBitmap);
  //TPicture.RegisterFileFormat('jpeg', 'JPEG File', TGdipBitmap);
  //TPicture.RegisterFileFormat('jpg', 'JPG File', TGdipBitmap);
finalization
  TPicture.UnregisterGraphicClass(TGdipBitmap);
end.
